//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#ifndef __ELASTOS_TIMEPEG_SLOT_H_
#define __ELASTOS_TIMEPEG_SLOT_H_

#include <elatypes.h>
_ELASTOS_NAMESPACE_USING

/*
 * A 64 bit counter
 */
typedef struct
{
    UInt32 high;
    UInt32 low;
} TIMESTAMP;

/*
 * The system-wide list of timepeg slots constitutes a directed graph.
 * This is because a particular slot may have any number of predecessors.
 * We don't attempt to record all possible predecessors.
 * We record a finite number.
 * If a timepeg slot has more than TIMEPEG_SLOT_PREDS predecessors then
 * XXXX drops some info on the floor
 */

#define TIMEPEG_NR_PREDS    16

/*
 * TST_TIMES is the size of the value array which stored the cost CPU cycles.
 * what's more, it specified the number of cost CPU cycles that we should get
 * and store to value array. The values which are more than TST_TIMES would be
 * skipped, we only measure the first TST_TIMES data.
 */

#if (_TEST_TYPE == 3)     /* Test for schedule performance */ \
    || (_TEST_TYPE == 21) /* Test for x86 system clock interruption \
                             response performance */ \
    || (_TEST_TYPE == 22) /* Test for x86 disable and restore \
                             preemption performance */ \
    || (_TEST_TYPE == 23) /* Test for x86 disable and restore \
                             interruption performance */

#define TST_TIMES 10000

#endif // _TEST_TYPE == 3 || ...

/* Mode bits */
#define TIMEPEG_MODE_INITIALISED    1   /* It has been constructed */
#define TIMEPEG_MODE_FULL           2   /* All timepeg arcs in preds[]
                                           are used */
#define TIMEPEG_MODE_DEAD           4
                        /* Flag: something wrong - ignore this timepeg
                         * from now on.
                         */

/*
 *  Edit Record by RenChi:
 *  comment the content of spinlock
 *  comment the content of line number
 *  comment the content of multi-CPUs
 */
struct timepeg_arc;
struct timepeg_slot;

struct timepeg_arc
{
    /* This points at the most-recently-called timepeg */
    struct timepeg_slot *timepeg;
    /* Accumulated time on this arc */
    TIMESTAMP acc_tp;
    /* longest and shortest transit times*/
    TIMESTAMP min_tp, max_tp;
    /* sub-longest and sub-shortest transit times*/
    TIMESTAMP smin_tp, smax_tp;
    /* The number of times this arc was used */
    unsigned long nr_times;
};

struct timepeg_slot
{
    const char *name;               /* Human readable identifier*/
    /* Name of the timepeg we're directed at*/
    const char *directee_name;

    struct timepeg_slot *next;  /* Singly linked, pointing next timepeg_slot*/

    short mode_bits;            /* state, initialization/full/dead*/

    /* If it's a directed timepeg,
       previous timepeg_slot(assignment or default)*/
    struct timepeg_slot *directed_pred;

    /* We logically separate each CPU */
    /* But here only one CPU! So I modify multiprocess to uniprocessor*/

    TIMESTAMP departure_tp;     /* the time point most-recently-springed */

    /*
     * A simple array of arcs to predecessors
     * Each entry represents a predecessor.  That is, a most-recently-called
     * TIMEPEG().*/
    struct timepeg_arc preds[TIMEPEG_NR_PREDS];

    UInt32 value[TST_TIMES];
};

struct timepeg_slot_percpu
{
    TIMESTAMP departure_tp;     /* the time point most-recently-springed */

    /*
     * A simple array of arcs to predecessors
     * Each entry represents a predecessor.  That is, a most-recently-called
     * TIMEPEG().
     */
    struct timepeg_arc preds[TIMEPEG_NR_PREDS];
};

#endif  /* __ELASTOS_TIMEPEG_SLOT_H_ */
